#include "OgreGLESGpuProgramManager.h"
#include "OgreLogManager.h"

namespace Ogre
{
	GLESGpuProgramManager::GLESGpuProgramManager()
	{
		ResourceGroupManager::getSingleton()._registerResourceManager(mResourceType, this);
	}

	GLESGpuProgramManager::~GLESGpuProgramManager()
	{
		ResourceGroupManager::getSingleton()._unregisterResourceManager(mResourceType);
	}

	bool GLESGpuProgramManager::registerProgramFactory(const String& syntaxCode,
														CreateGpuProgramCallback createFn)
	{
		return mProgramMap.insert(ProgramMap::value_type(syntaxCode, createFn)).second;
	}

	bool GLESGpuProgramManager::unregisterProgramFactory(const String& syntaxCode)
	{
		return mProgramMap.erase(syntaxCode) != 0;
	}

	Resource* GLESGpuProgramManager::createImpl(const String& name,
												ResourceHandle handle,
												const String& group, bool isManual,
												ManualResourceLoader* loader,
												const NameValuePairList* params)
	{
		NameValuePairList::const_iterator paramSyntax, paramType;

		if (!params || (paramSyntax = params->find("syntax")) == params->end() ||
			(paramType = params->find("type")) == params.end())
		{
			OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
				"You must supply 'syntax' and 'type' parameters",
				"GLESGpuProgramManager::createImpl");
		}

		ProgramMap::const_iterator iter = mProgramMap.find(paramSyntax->second);
		if (iter == mProgramMap.end())
		{
			return 0;
		}

		GpuProgramType gpt;
		if (paramType->second == "vertex_program")
		{
			gpt = GPT_VERTEX_PROGRAM;
		}
		else
		{
			gpt = GPT_FRAGMENT_PROGRAM;
		}

		return (iter->second)(this, name, handle, group, isManual,
								loader, gpt, paramSyntax->second);
	}

	Resource* GLESGpuProgramManager::createImpl(const String& name,
												ResourceHandle handle,
												const String& group, bool isManual,
												ManualResourceLoader* loader,
												GpuProgramType gptype,
												const String& syntaxCode)
	{
		class DummyGpuProgram : public GpuProgram
		{
		public:
			DummyGpuProgram(ResourceManager* creator, const String& name, ResourceHandle handle,
				const String& group, bool isManual, ManualResourceLoader* loader)
				: GpuProgram(creator, name, handle, group, isManual, loader)
			{};

			void unloadImpl(void) {};

			void loadFromSource(void) {};
		};
		return OGRE_NEW DummyGpuProgram(this, name, handle, group,
			isManual, loader);
	}
}
